#include <log/qls_log.h>

#include <QDir>
#include <QApplication>
#include <QDateTime>
#include <QMutexLocker>

#include <settings/qls_settings.h>

using namespace QsLogging;

/* static  */
QMutex QLsLog::m_instanceMutex;       /* 实例锁 */
QLsLog *QLsLog::m_instance = nullptr; /* 实例 */

QLsLog::QLsLog()
{
    /* 初始化日志机制 */
    Logger &logger = Logger::instance();
    logger.setLoggingLevel(QsLogging::TraceLevel);
}

/* 单例模式：懒汉式 + 双检锁 */
QLsLog &QLsLog::GetInstance()
{
    if (!m_instance) {
        QMutexLocker instanceLocker(&m_instanceMutex);
        if (!m_instance)
            m_instance = new QLsLog();
    }
    return *m_instance;
}

/* 销毁实例 */
void QLsLog::DestroyInstance()
{
    if (m_instance) {
        QMutexLocker instanceLocker(&m_instanceMutex);
        if (m_instance) {
            delete m_instance;
            m_instance = nullptr;
        }
    }
}

/* 设置日志输出文件 */
void QLsLog::SetLogPath(const QString &logPath)
{
    Logger &logger = Logger::instance();
    m_logPath = logPath;

    /* 如果是空路径，则创建到默认位置 */
    if (m_logPath.isEmpty()) { /* 默认路径 */
        m_logPath =
            QDir(QLsSettings::getWorkSpace())
                .filePath(QString("log/%1.log")
                              .arg(QDateTime::currentDateTime().toString(
                                  "yyyyMMddhhmmss")));
    }

    /* 路径校验 - QsLog的输出文件必须存在路径，才能创建日志文件 */
    /* 获取最后一个文件分隔符的位置 */
    int lastIndex = -1;
    if ((lastIndex = m_logPath.lastIndexOf("/")) == -1 &&
        (lastIndex = m_logPath.lastIndexOf("\\")) == -1)
        return;
    /* 提取输出文件的路径 */
    QString path(m_logPath.left(lastIndex));
    /* 校验路径是否存在，如果不存在则创建 */
    QDir dir = QDir(QLsSettings::getWorkSpace());
    if (!dir.cd(path))
        dir.mkpath(path);

    /* 添加文件为目的地(日志输出文件) */
    DestinationPtr fileDestination(DestinationFactory::MakeFileDestination(
        m_logPath, EnableLogRotation, MaxSizeBytes(512 * 1024),
        MaxOldLogCount(5)));
    logger.addDestination(fileDestination);
}

/* 设置日志输出界面 */
void QLsLog::SetLogWindow(QObject *window)
{
    if (!window)
        return;

    Logger &logger = Logger::instance();
    m_window = window;

    /* 添加QObject为目的地 */
    DestinationPtr objectDestination(DestinationFactory::MakeFunctorDestination(
        m_window, SLOT(slotWriteLog(QString, int))));
    logger.addDestination(objectDestination);
}
